/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.close.position.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopes.bizz.close.common.constant.CloseModuleEnums;
import com.hopes.bizz.close.common.constant.PositionProperties;
import com.hopes.bizz.close.common.constant.VisitorDicConstant;
import com.hopes.bizz.close.position.dto.HisHazardCarDTO;
import com.hopes.bizz.close.position.dto.HisHazardCarLimitDTO;
import com.hopes.bizz.close.position.entity.ClosedHazardCarPositionHisEntity;
import com.hopes.bizz.close.position.dto.ClosedHazardCarPositionHisExcelDTO;
import com.hopes.bizz.close.position.vo.ClosedHazardCarPositionHisExcelVO;
import com.hopes.bizz.close.position.mapper.ClosedHazardCarPositionHisMapper;
import com.hopes.bizz.close.position.service.ClosedHazardCarPositionHisService;
import com.hopes.bizz.close.visitor.entity.ClosedHazardCarApplyEntity;
import com.hopes.bizz.close.visitor.entity.ClosedHazardCarRecordEntity;
import com.hopes.bizz.close.visitor.service.ClosedHazardCarApplyService;
import com.hopes.bizz.close.visitor.service.ClosedHazardCarRecordService;
import com.hopes.bizz.common.core.util.DateUtils;
import com.hopes.boss.common.core.exception.BizException;
import com.hopes.boss.common.core.util.R;
import com.hopes.boss.common.entity.ValidateImportBO;
import com.hopes.boss.common.excel.vo.ErrorMessage;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 危化品车辆定位历史
 *
 * @author pig
 * @date 2024-02-04 16:14:24
 */
@Service
@RequiredArgsConstructor
public class ClosedHazardCarPositionHisServiceImpl extends ServiceImpl<ClosedHazardCarPositionHisMapper, ClosedHazardCarPositionHisEntity> implements ClosedHazardCarPositionHisService {


    private final PositionProperties positionProperties;
    private final ClosedHazardCarApplyService closedHazardCarApplyService;

    @Override
    public ValidateImportBO<ClosedHazardCarPositionHisExcelDTO> validateImport(List<ClosedHazardCarPositionHisExcelDTO> excelDTOList) {
        ValidateImportBO<ClosedHazardCarPositionHisExcelDTO> bo = new ValidateImportBO<>();
        List<ErrorMessage> errorMessageList = new ArrayList<>();
        List<ClosedHazardCarPositionHisExcelDTO> saveList = new ArrayList<>(excelDTOList);
        int successNum = excelDTOList.size();
        int failedNum = 0;

        bo.setErrorMessages(errorMessageList);
        bo.setSaveList(saveList);
        bo.setSuccessNum(successNum);
        bo.setFailedNum(failedNum);
        return bo;
    }

    @Override
    public ClosedHazardCarPositionHisEntity importDtoToEntity(ClosedHazardCarPositionHisExcelDTO excelDto) {
        ClosedHazardCarPositionHisEntity entity= new ClosedHazardCarPositionHisEntity();
        BeanUtils.copyProperties(excelDto, entity);
        return entity;
    }

    @Override
    public ClosedHazardCarPositionHisExcelVO exportEntityToVo(ClosedHazardCarPositionHisEntity entity) {
        ClosedHazardCarPositionHisExcelVO excelVO = new ClosedHazardCarPositionHisExcelVO();
        BeanUtils.copyProperties(entity, excelVO);
        return excelVO;
    }

    @Override
    public List<ClosedHazardCarPositionHisEntity> queryHazardCarPositionHisTrack(String licencePlateNum) {
        final LambdaQueryWrapper<ClosedHazardCarApplyEntity> wrapper = Wrappers.<ClosedHazardCarApplyEntity>lambdaQuery()
                .eq(ClosedHazardCarApplyEntity::getLicencePlateNum, licencePlateNum).last("limit 1").orderByDesc(ClosedHazardCarApplyEntity::getRealEnterTime);
        final ClosedHazardCarApplyEntity closedHazardCarApply = closedHazardCarApplyService.getOne(wrapper);
        if (ObjUtil.isNull(closedHazardCarApply) || ObjUtil.isNull(closedHazardCarApply.getRealEnterTime())) {
            return new ArrayList<>();
        }
        final HisHazardCarDTO hisHazardCarDTO = new HisHazardCarDTO();
        hisHazardCarDTO.setLicencePlateNum(licencePlateNum);
        hisHazardCarDTO.setOrgId(closedHazardCarApply.getOrgId());
        hisHazardCarDTO.setStartTime(closedHazardCarApply.getRealEnterTime());
        hisHazardCarDTO.setEndTime(Optional.ofNullable(closedHazardCarApply.getRealLeaveTime()).orElse(Calendar.getInstance().getTime()));
        final List<ClosedHazardCarPositionHisEntity> closedHazardCarPositionHisList = queryHisHazardCarPositionList(hisHazardCarDTO);
        if (CollUtil.isEmpty(closedHazardCarPositionHisList)) {
            return closedHazardCarPositionHisList;
        }
        final ClosedHazardCarPositionHisEntity firstItem = closedHazardCarPositionHisList.get(0);
        final ClosedHazardCarPositionHisEntity lastItem = closedHazardCarPositionHisList.get(closedHazardCarPositionHisList.size() - 1);
        firstItem.setDirection(CloseModuleEnums.InOutDirectionEnum.in.name());
        Optional.ofNullable(closedHazardCarApply.getRealLeaveTime()).ifPresent((item) -> {
            lastItem.setDirection(CloseModuleEnums.InOutDirectionEnum.out.name());
        });
        closedHazardCarPositionHisList.add(0, firstItem);
        closedHazardCarPositionHisList.add(lastItem);
        return closedHazardCarPositionHisList;
    }

    @Override
    public List<ClosedHazardCarPositionHisEntity> queryHisHazardCarPositionList(HisHazardCarDTO hisHazardCarDTO) {
        if (ObjUtil.isNull(hisHazardCarDTO) || ObjUtil.isNull(hisHazardCarDTO.getOrgId())
                || StrUtil.isEmpty(hisHazardCarDTO.getLicencePlateNum()) || ObjUtil.isNull(hisHazardCarDTO.getStartTime()) || ObjUtil.isNull(hisHazardCarDTO.getEndTime())) {
            return new ArrayList<>();
        }
        final LambdaQueryWrapper<ClosedHazardCarPositionHisEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ClosedHazardCarPositionHisEntity::getOrgId, hisHazardCarDTO.getOrgId())
                .eq(ClosedHazardCarPositionHisEntity::getLicencePlateNum, hisHazardCarDTO.getLicencePlateNum())
                .le(ClosedHazardCarPositionHisEntity::getDataTime, hisHazardCarDTO.getEndTime())
                .ge(ClosedHazardCarPositionHisEntity::getDataTime, hisHazardCarDTO.getStartTime());
        return getBaseMapper().selectList(queryWrapper);
    }

    @Override
    public List<ClosedHazardCarPositionHisEntity> queryHisHazardCarPositionLimitList(HisHazardCarLimitDTO hisHazardCarLimitDTO) {
        final LambdaQueryWrapper<ClosedHazardCarPositionHisEntity> queryWrapper = Wrappers.<ClosedHazardCarPositionHisEntity>lambdaQuery();
        queryWrapper.eq(ClosedHazardCarPositionHisEntity::getOrgId, hisHazardCarLimitDTO.getOrgId());
        queryWrapper.ge(ClosedHazardCarPositionHisEntity::getDataTime, hisHazardCarLimitDTO.getStartTime());
        queryWrapper.eq(ClosedHazardCarPositionHisEntity::getLicencePlateNum, hisHazardCarLimitDTO.getLicencePlateNum());
        if (hisHazardCarLimitDTO.getPositionLimitEnum().equals(CloseModuleEnums.HisPositionLimitEnum.HOUR)) {
            if (hisHazardCarLimitDTO.getTimeLength() > positionProperties.getHisPositionTimeLengthLimitHour()) {
                throw  new BizException("最大查询时长为" + positionProperties.getHisPositionTimeLengthLimitHour() + "小时");
            }
            queryWrapper.le(ClosedHazardCarPositionHisEntity::getDataTime, DateUtils.addHour(hisHazardCarLimitDTO.getStartTime(), hisHazardCarLimitDTO.getTimeLength()));
        } else if (hisHazardCarLimitDTO.getPositionLimitEnum().equals(CloseModuleEnums.HisPositionLimitEnum.MINUTE)) {
            if (hisHazardCarLimitDTO.getTimeLength() > positionProperties.getHisPositionTimeLengthLimitMinute()) {
                throw  new BizException("最大查询时长为" + positionProperties.getHisPositionTimeLengthLimitMinute() + "分钟");
            }
            queryWrapper.le(ClosedHazardCarPositionHisEntity::getDataTime, DateUtils.addMinute(hisHazardCarLimitDTO.getStartTime(), hisHazardCarLimitDTO.getTimeLength()));
        } else {
            throw new BizException("参数错误");
        }
        return this.list(queryWrapper);
    }
}
